var FOXTORRENT_GUID = "foxtorrent2@foxtorrent.com";

// Keep track of whether or not the client is installed.
var ft_RSInstalled = false;

// Ping the client. If we get a response, we'll mark the client as installed. 
ft_send_message("http://127.0.0.1:9421/api?cid=2&function=ping", function(){ft_RSInstalled = true});

// Schedule the client to be intalled in two seconds if we never get a response from our ping.
setTimeout(function(){if(!ft_RSInstalled) ft_installRS()}, 2000);

ft_trustFlash();

// Just because I think it's funny.
ft_log("IN UR FIREFOX, SHARIN UR FILEZ");

// Installs the Red Swoosh client.
// Also configures flash to trust the FoxTorrent directory.
function ft_installRS(){
	// Get extension local directory from our extension's GUID
    var ext = Components.classes["@mozilla.org/extensions/manager;1"]
		.getService(Components.interfaces.nsIExtensionManager)
		.getInstallLocation(FOXTORRENT_GUID)
		.getItemLocation(FOXTORRENT_GUID);

	// Run our installer                    
	     if (navigator.userAgent.match(/linux.*86/i)) ft_runApp(false, ext.path + "/binaries/RSInstaller-Linux-i386");
	else if (navigator.userAgent.match(/macintosh/i)) ft_runApp(false, ext.path + "/binaries/RSInstaller-MacOS-universal");
	else if (navigator.userAgent.match(/windows/i))   ft_runApp(false, ext.path + "\\binaries\\setup.exe", " silent");
	else ft_log("Couldn't determine platform from userAgent: " + navigator.userAgent);
}


function ft_trustFlash(){
	// Get extension local directory from our extension's GUID
    var ext = Components.classes["@mozilla.org/extensions/manager;1"]
		.getService(Components.interfaces.nsIExtensionManager)
		.getInstallLocation(FOXTORRENT_GUID)
		.getItemLocation(FOXTORRENT_GUID);
                   
	     if (navigator.userAgent.match(/linux.*86/i)){}
	else if (navigator.userAgent.match(/macintosh/i)){
		exitcode = ft_runApp(true, ext.path + "/binaries/trust_flash_mac", ext.path + "/content");
		if(exitcode) ft_log("Failed to set Flash trust policy, exit code: " + exitcode);
	}
	else if (navigator.userAgent.match(/windows/i)){
		exitcode = ft_runApp(true, ext.path + "\\binaries\\foxtorrent.exe", ext.path + "\\content");
		if(exitcode) ft_log("Failed to set Flash trust policy, exit code: " + exitcode);
	}
	else ft_log("Couldn't determine platform from userAgent: " + navigator.userAgent);
}



// Runs an executable. Takes the filename of the executable, and any number of command line arguments for it.
function ft_runApp(blocking, filename){
	var process;
	try {
		var nsILocalFile = Components.classes["@mozilla.org/file/local;1"].getService(Components.interfaces.nsILocalFile);
		nsILocalFile.initWithPath(filename);
		if(nsILocalFile.exists()){
			var args = new Array();
			for(var i = 2; i < arguments.length; i++) args.push(arguments[i]);
			process = Components.classes["@mozilla.org/process/util;1"].getService(Components.interfaces.nsIProcess);
			process.init(nsILocalFile);
			process.run(blocking, args, args.length);
		}
		else{
			ft_log("Couldn't start process: '" + filename + "', file doesn't exist.");
		}
	}
	catch(e) {
		ft_log("Error running executable: " + filename + ", properties below.");
		for(x in e) ft_log("Error(" + x + "): " + e[x]);
	}
	if(blocking) return process.exitValue;
	else return;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Everything below here just makes sure torrent files automatically get saved to disk without prompting the user. ///
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

var ft_mime_ds;
ft_verify_mimetypes();

function ft_verify_mimetypes(){

	// First thing we do, figure out the name of the file in which mimetype info is stored.
	// this file is "mimeTypes.rdf", somewhere inside the currently active profile's directory.

	// Get the mozilla directory service, and then look up our filename with it. We need the "nsIProperties" interface, because
	// that's where the "get" method that lets us look up our file by key is.
	// UMimTyp is a constant defined in the FireFox source code as NS_APP_USER_MIMETYPES_50_FILE, which is the file in which
	// mimeType info is stored, for the current user.
	var dirService = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties);
	var fileName = dirService.get("UMimTyp", Components.interfaces.nsIFile).path;

	// Then, we need to get the mozilla RDF service, so we can tweak our RDF file.
	var rdfService = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);

	// Now we open up an RDF data source using our file. We include "file://", because this method takes URIs, not filenames.
	// ft_mime_ds is an instance of "nsIRDFDataSource";
	ft_mime_ds = rdfService.GetDataSource("file://" + fileName);

	// Data sources load asynchronously, so we have to wait until it's loaded.
	// This is the object that will observe the XML/RDF load progress.
	var rdfObserver = {
		onBeginLoad: function(sink){},
		onInterrupt: function(sink){},
		onResume: function(sink){},
		onEndLoad: function(sink){ ft_process_rdf(); },
		onError: function(sink, status, errorMsg){ ft_log("RDF LOADING FAILED: " + errorMsg); }
	};

	// Get the remote data source interface for the file we're working on.
	var remote = ft_mime_ds.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource);

	// If the load is already complete, cool.
	if (remote.loaded) ft_process_rdf();

	// XML/RDF files requires this "sink" thing, according to mozilla documentation.
	else ft_mime_ds.QueryInterface(Components.interfaces.nsIRDFXMLSink).addXMLSinkObserver(rdfObserver);
}

// This runs after we've finished loading our RDF data source.
function ft_process_rdf(){

	// Get a reference to the global RDF service.
	var rdfService = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);
	
	// These are the mimetypes we care about.
	var mimeTypes = [ "application/x-bittorrent" ]; // Maybe also: application/x-download
	
	// Get a container, which are used for mimetype sequences (RDF:Seq elements in XML), and initialize it with the
	// root mimetype resource and our current data source.
	var container = Components.classes["@mozilla.org/rdf/container;1"]
		.createInstance().QueryInterface(Components.interfaces.nsIRDFContainer);
	container.Init(ft_mime_ds, rdfService.GetUnicodeResource("urn:mimetypes:root"));
	
	// Figure out if these mimetypes are registered. Register them if they're not.
	for(var i = 0; i < mimeTypes.length; i++){
		
		var resources = {
			"extApp": rdfService.GetUnicodeResource("urn:mimetype:externalApplication:" + mimeTypes[i]),
			"handler": rdfService.GetUnicodeResource("urn:mimetype:handler:" + mimeTypes[i]),
			"type": rdfService.GetUnicodeResource("urn:mimetype:" + mimeTypes[i])
		}
		
		var properties = {
			"extApp": {
				"http://home.netscape.com/NC-rdf#prettyName": rdfService.GetLiteral(""),
				"http://home.netscape.com/NC-rdf#path": rdfService.GetLiteral("")
			},
			"handler":{
				"http://home.netscape.com/NC-rdf#alwaysAsk": rdfService.GetLiteral("false"),
				"http://home.netscape.com/NC-rdf#saveToDisk": rdfService.GetLiteral("true"),
				"http://home.netscape.com/NC-rdf#externalApplication": resources["extApp"]
			},
			"type":{
				"http://home.netscape.com/NC-rdf#value": rdfService.GetLiteral(mimeTypes[i]),
				"http://home.netscape.com/NC-rdf#editable": rdfService.GetLiteral("true"),
				"http://home.netscape.com/NC-rdf#fileExtensions": rdfService.GetLiteral("torrent"),
				"http://home.netscape.com/NC-rdf#description": rdfService.GetLiteral(""),
				"http://home.netscape.com/NC-rdf#handlerProp": resources["handler"]
			}
		}
		
		// Add this mimetype to the root if we need to.
		if(container.IndexOf(resources["type"]) == -1) container.AppendElement(resources["type"]);
		
		// Set all the properties for our resources.
		for(r in resources){
			for(p in properties[r]){
				var property = rdfService.GetUnicodeResource(p);
				if(!ft_mime_ds.HasAssertion(resources[r], property, properties[r][p], true))
					ft_mime_ds.Assert(resources[r], property, properties[r][p], true);
			}
		}
	}
	
	// write to disk.
	ft_mime_ds.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource).Flush();		
}
